# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 -------------------------------------------------
    File Name:     DBClient.py
    Description:   数据库的连接工具
 -------------------------------------------------
 支持:
 1. mysql
 """

import pymysql


class BaseDB:
    """
    基类数据库

    主要用于关闭数据库时判断共有的父类
    """

    cursor = None
    conn = None

    def execute(self, sql: str, args=None):
        """执行SQL语句"""
        try:
            self.cursor.execute(sql, args)
            return self.cursor.fetchone()
        except Exception as e:
            print('执行SQL失败:', e)
            return e

    def execute_all(self, sql: str, args=None):
        """执行SQL语句"""
        try:
            self.cursor.execute(sql, args)
            return self.cursor.fetchall()
        except Exception as e:
            print('执行SQL失败:', e)
            return e

    def close(self):
        """关闭数据库连接"""
        self.cursor.close()
        self.conn.close()


class MySqlDB(BaseDB):
    def __init__(self, db_config: dict):
        """初始化数据库连接"""
        # self.db_config = db_config
        self.conn = pymysql.connect(**db_config, autocommit=True)
        self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)


class OracleDB(BaseDB):
    def __init__(self, db_config: dict):
        """初始化数据库连接"""
        # self.db_config = db_config
        self.conn = pymysql.connect(**db_config, autocommit=True)
        self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)


class DBClient:
    """数据库的连接工具"""

    def init_connect(self, db_config):
        """初始化数据库连接"""
        if isinstance(db_config, dict):
            # 单个数据库的配置
            self.__create_db_connection(db_config)
        elif isinstance(db_config, list):
            # 多个数据库的连接
            for db_config_item in db_config:
                if isinstance(db_config_item, dict):
                    self.__create_db_connection(db_config_item)
        else:
            raise TypeError("数据库配置格式错误: must be a dict or a list")

    def __create_db_connection(self, db_config: dict):
        """创建数据库连接"""
        if not (db_config.get("name") and db_config.get("type") and db_config.get("config")):
            raise ValueError("不支持的数据库类型: {}".format(db_config.get("type")))

        if db_config.get("type") == "mysql":
            # 连接mysql数据库
            setattr(self, db_config.get("name"), MySqlDB(db_config.get("config")))
        elif db_config.get("type") == "sqlite":
            # 连接sqlite数据库
            pass
        elif db_config.get("type") == "mssql":
            # 连接mssql数据库
            pass

    def close_db_connection(self):
        """关闭数据库连接"""
        # 遍历所有属性, 判断是否为MySqlDB对象, 如果是则调用close方法
        for db_name in dir(self):
            # 过滤掉特殊属性
            if db_name.startswith("__") or db_name.endswith("__"):
                continue
            # 判断是否为MySqlDB对象, 如果是则调用close方法
            if isinstance(getattr(self, db_name), BaseDB):
                getattr(self, db_name).close()


if __name__ == '__main__':
    db_config = [
        {
            "name": "test",
            "type": "mysql",
            "config": {
                "host": "127.0.0.1",
                "port": 3306,
                "user": "root",
                "password": "Hell12345..",
            }
        }
    ]

    db_client_obj = DBClient()
    db_client_obj.init_connect(db_config=db_config)

    # 执行SQL语句
    res = db_client_obj.test.execute("select Host, User from mysql.user")
    print(res)
    res = db_client_obj.test.execute_all("select Host, User from mysql.user")
    print(res)

    db_client_obj.close_db_connection()

db_obj = DBClient()
